/* eslint-disable */
/**
 * @name 接收一个promise的iterable类型（注：Array，Map，Set都属于ES6的iterable类型）的输入，并且只返回一个Promise实例，那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束，或者输入的iterable里没有promise了的时候。它的reject回调执行是，只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误，并且reject的是第一个抛出的错误信息
 * @param {promise} promises
 * @param {function} cb 回调函数，可空
 * @returns
 */
const all = function all(promises, cb) {
  if (!Array.isArray(promises)) throw new Error('First argument must be an array.');
  let _resolve, _reject;
  const resPromise = new Promise((resolve, reject) => {
    _resolve = resolve;
    _reject = reject;
  });
  let len = 0;
  let index = 0;
  const res = [];
  for (const promise of promises) {
    const i = index++;
    Promise.resolve(promise).then(
      ret => {
        len++;
        res[i] = ret;
        if (len === promises.length) {
          if (typeof cb === 'function') {
            cb.call(this, null, res);
          } else if (_resolve) {
            _resolve(res);
          }
        }
      },
      err => {
        if (typeof cb === 'function') {
          cb.call(this, err);
        } else if (_reject) {
          _reject(err);
        }
      }
    );
  }
  if (!cb) {
    return resPromise;
  }
};

export default all;
